package com.bridgeQQ.client.control.connection.bs.connection
{
	import com.bridgeQQ.client.core.connection.IConnection;
	import com.bridgeQQ.client.events.SendEvent;
	
	import flash.events.Event;
	import flash.events.EventDispatcher;
	
	import log.LogFactory;
	
	import mx.core.Application;
	import mx.logging.ILogger;
	import mx.messaging.Consumer;
	import mx.messaging.Producer;
	import mx.messaging.events.ChannelEvent;
	import mx.messaging.events.ChannelFaultEvent;
	import mx.messaging.events.MessageAckEvent;
	import mx.messaging.events.MessageEvent;
	import mx.messaging.events.MessageFaultEvent;
	import mx.messaging.messages.AsyncMessage;
	import mx.messaging.messages.IMessage;
	
	public class BsConnection extends EventDispatcher implements IConnection
	{
		private var outbound:Producer;
		
		private var inbound:Consumer;
		
		private var handlerDef:Object;
		
		private var _userID:String;
		
		private var logger:ILogger = LogFactory.getLogger(this);
		
		public function BsConnection(outbound:Producer, inbound:Consumer)
		{
			this.outbound = outbound;
			this.inbound = inbound;
			this.inbound.addEventListener(MessageEvent.MESSAGE, onMessage);
			this.outbound.addEventListener(MessageAckEvent.ACKNOWLEDGE, onAck);
			outbound.addEventListener(ChannelEvent.DISCONNECT, onFault);
            outbound.addEventListener(MessageFaultEvent.FAULT, onFault);
            outbound.addEventListener(ChannelFaultEvent.FAULT, onFault);
		}
		
		public function send(handlerName:String, ...params):String
		{
			//header {destination: desUserID}
			//body:{handler:name ,from: userID,  params: params, messageId : messageId}
			var message:IMessage = new AsyncMessage();
			message.headers.destination = params.shift();	
			message.body.handler = handlerName;
			message.body.from = _userID;
			message.body.params = params;
			//message.body.messageId = _userID + new Date().time;
			message.timestamp = new Date().time;
			Application.application.callLater(pushToServer,[message]);
			var msgID:String =  message.messageId;
			logger.debug("send message id: " + msgID);
			return msgID;
		}
		
		private function pushToServer(message:IMessage):void
		{
			outbound.send(message);
		}
		
		public function set handlers(value:Object):void
		{
			handlerDef = value;
		}
		
		
		private function onMessage(event:MessageEvent):void
		{
			var message:IMessage = event.message;
			var handler:Function = handlerDef[message.body.handler];
			if(handler == null)
			{
				return;
			}
			var params:Array = message.body.params;
			if(message.body.from && params != null && params.length > 0)
			{
				params.unshift(message.body.from);
				handler.apply(null, params);
			}
		}
		
		private function onAck(event:MessageAckEvent):void
		{
			logger.debug("recieved message acknowledge: " + event.correlationId);
			this.dispatchEvent(new SendEvent(SendEvent.SUCCESS, event.correlationId));
			
		}
		
		private function onFault(event:Event):void
		{
        	this.dispatchEvent(new SendEvent(SendEvent.ERROR, ""));
		}
		
		public function set userID(value:String):void
		{
			this._userID = value;
		}
	}
}